home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-15 | 29.1 KB | 836 lines | [TEXT/MPS ] |
- *
- * Apple Macintosh Developer Technical Support
- *
- *
- * CLUTSample
- *
- *
- * Loosely based in the sample SAMPLE this program shows
- * how to create a window and display on it the colors of the CLUT
- * associated with the device the window sits on top of.
- *
- * Left to the curious reader are some improvements such as, remembering the
- * positions of each open window, so if you use this program to monitor your
- * color tables it will position the windows in the last place you opened them.
- * The treatment of direct devices is kind of 'casual' a better color display may
- * be appropriate. Last, it may be desireable to change the size of the color
- * rectangles depending on the depth of the color table.
-
- * Check Sample sources for more detailed documentation.
-
- * ================================================
- * -------------- INCLUDES SECTION ----------------
- * ================================================
-
- PRINT PUSH,OFF ; don't print any of this stuff
-
- INCLUDE 'ToolEqu.a'
- INCLUDE 'Traps.a'
- INCLUDE 'PackMacs.a'
- INCLUDE 'QuickEqu.a'
- INCLUDE 'SysEqu.a'
- INCLUDE 'CLUTSample.inc1.a' ; all our macros and data templates
-
- PRINT POP ; restore the PRINT options
-
-
- * ================================================
- * --------- DATA STORAGE ALLOCATION ------------
- * ================================================
- * Global data storage. All global memory is allocated here. The
- * Linker will load all global data offset from A5, and the Asm knows this.
- * Therefore, no reference to (A5) is required in the code. Hooray!
- * Here we declare two data structures using our templates defined previously.
- * They must be EXPORTed here for other files that need to IMPORT them.
-
- EXPORT (QD,G):DATA
-
- QD DS MyQDGlobals ; QuickDraw's globals
- G DS AppGlobals ; application's globals
-
-
- * ================================================
- * --------- INITIALIZATION PROC ------------
- * ================================================
- SEG 'Initialize' ; case sensitive
- Initialize PROC ; Initialize everything
-
- CountReg EQU D4 ; temporary registor to count loops
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- CurMBar DS.L 1 ; local handle to our menubar
- TheEvent DS EventRecord ; local copy of the event record
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT GoGetRect,AlertUser,SysEnvirons, \
- OpenClutWind, \
- TrapAvailable ; linked in with Interface.o
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVEM.L CountReg,-(SP) ; save the current registor values
- MOVE.W #False,G.InBackground ; we start out in the foreground
- MOVE.W #True,G.Stopped ; we'll start with the red light on
-
- * ------------- INITIALIZE MANAGERS -------------
-
- @1 PEA QD.thePort ; initialize all of the Managers
- _InitGraf ; please don't flush my events
- _InitFonts
- _InitWindows
- _InitMenus
- _TEInit
- CLR.L -(SP)
- _InitDialogs
- _InitCursor
-
- * Call MPPOpen and ATPLoad at this point to initialize AppleTalk, if you are using it.
- * NOTE -- It is no longer necessary, and actually unhealthy, to check PortBUse and
- * SPConfig before opening AppleTalk. The drivers are capable of checking for port
- * availability themselves. This next bit of code is necessary to allow the default
- * button of our alert be outlined.
-
- * ------------- WASTE THREE EVENTS -------------
-
- MOVE.W #2,CountReg ; set register value to loop 3 times
- Loop CLR.W -(SP) ; space for result
- MOVE.W #EveryEvent,-(SP) ; the events we want
- PEA TheEvent(A6) ; pass a pointer to our event
- _EventAvail
- MOVE.W (SP)+,D0 ; result code
- DBF CountReg,Loop ; decrement count, if count < 0 then continue
-
- * ------------- GET THE ENVIRONMENT -------------
-
- CLR.W -(SP) ; create space for result
- MOVE.W #EnvironsVersion,-(SP) ; version of SysEnvirons we want
- PEA G.Mac ; the global environment record
- JSR SysEnvirons ; we can ignore any errors here,
- MOVE.W (SP)+,D0 ; SysEnvirons will fill in regardless
- MOVE.W G.Mac.MachineType,D0 ; negitive value means old ROMs
- BPL.S @2 ; 128k ROMs or better, continue on
- JMP AlertUser ; we don't want to run on 64k ROMs
-
- * ------------- TEST FOR WAITNEXTEVENT -------------
- * 1.02 - Move TrapAvailable call to after SysEnvirons so that
- * we can tell in TrapAvailable if a tool trap value is out of range.
-
- @2 CLR.W -(SP) ; space for result of trap test
- MOVE.W #WaitNextEvent,-(SP) ; pass the trap number of WaitNextEvent trap
- BSR TrapAvailable ; test for this trap
- MOVE.W (SP)+,G.HasWNEvent ; put the result in our global flag
-
-
- MOVE.L applLimit,D1 ; get pointer to ApplLimit
- MOVE.L applZone,D0 ; get pointer to ApplicZone
- SUB.L D0,D1 ; subtract the ApplicZone from ApplLimit
- CMPI.L #MinHeap,D1 ; do we have enough memory?
- BPL.S @3 ; yes we do, continue on
- JMP AlertUser ; no, report the error
-
- @3 _PurgeSpace ; results will be in A0 and D0
- CMPI.L #MinSpace,D0 ; do we have enough purgeable space?
- BPL.S @4
- JMP AlertUser ; no, report the error
-
- * ------------- SET UP THE MENUS -------------
-
- @4 CLR.L -(SP) ; space for MenuBar handle
- MOVE.W #rMenuBar,-(SP) ; our MenuBar resource
- _GetNewMBar ; the modern way, get a MenuBar
- MOVE.L (SP),CurMBar(A6)
- _SetMenuBar
- MOVEA.L CurMBar(A6),A0 ; we're done with that handle
- _DisposHandle ; there is a result in D0
- CLR.L -(SP)
- MOVE.W #AppleMenu,-(SP)
- _GetMHandle ; put Apple menu handle on stack
- MOVE.L #'DRVR',-(SP) ; get all the DAs
- _AddResMenu
- _DrawMenuBar
-
- Exit MOVEM.L (SP)+,CountReg ; restore the registors
- UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo Initialz ; this name will appear in the debugger
- ENDP
- * ================================================
- * PROCEDURE OpenClutWind();
- * ================================================
- SEG 'Main' ; case sensitive
- OpenClutWind PROC
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; passed parameter of the window pointer
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT DrawClut,NulMouse,OpenWindow
- WITH StackFrame,ClutWData ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- Clr.l -(SP)
- Move.W #rWindow,-(SP)
- Move.L #ClutWDataSize,-(SP)
- PEA DrawClut
- PEA NulMouse
- JSR OpenWindow
- MOVE.L (SP)+,A0
- Exit
- UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo OpenClutWind
- ENDP
-
-
-
- * ================================================
- * PROCEDURE DoUpdate(window: WindowPtr);
- * ================================================
- * This is called when an update event is received for a window.
- * It calls DrawWindow to draw the contents of an application window.
- * As an efficiency measure that does not have to be followed, it
- * calls the drawing routine only if the visRgn is non-empty. This
- * will handle situations where calculations for drawing or drawing
- * itself is very time-consuming.
-
- SEG 'Main' ; case sensitive
- DoUpdate PROC
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- WindowPtr DS.L 1 ; passed parameter of the window pointer
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT IsAppWindow,DrawWindow
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- CLR.W -(SP) ; space for result of IsAppWindow
- MOVE.L WindowPtr(A6),-(SP) ; pass the window pointer
- BSR IsAppWindow ; test if this window was ours
- MOVE.W (SP)+,D0
- CMPI.W #True,D0 ; it must be our window
- BNE.S Exit ; it wasn't our window
-
- MOVE.L WindowPtr(A6),-(SP) ; update only the visible region
- _BeginUpDate ; region of the window
- CLR.W -(SP) ; space for result
- MOVEA.L WindowPtr(A6),A0 ; the window pointer
- MOVE.L visRgn(A0),-(SP) ; the window's visRgn handle
- _EmptyRgn
- MOVE.W (SP)+,D0 ; result of EmptyRgn
- CMPI.W #True,D0 ; was the visRgn empty?
- BEQ.S @1 ; yes, then no update is needed
-
- Clr.l -(SP)
- MOVE.L WindowPtr(A6),-(SP)
- _GetWRefCon
- Move.l (SP)+,A2 ; Retrieve handle
- Move.l (A2),A0 ; Deref Handle
- Move.l (A0),A0 ; Get ProcPtr
- MOVE.L WindowPtr(A6),-(SP)
- JSR (A0) ; draw the window
-
- @1 MOVE.L WindowPtr(A6),-(SP) ; get pointer to window
- _EndUpdate
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo DoUpdate ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE DoActivate(window: WindowPtr; becomingActive: BOOLEAN);
- * ================================================
- * In this sample there is no other processing necessary other than what
- * the Window Manager has already done for us. This would be the place to
- * perform an activate on TextEdit records, controls, lists, update GrowIcon, etc.
-
- SEG 'Main' ; case sensitive
- DoActivate PROC
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- WindowPtr DS.L 1 ; passed parameter of the window pointer
- Active DS.W 1 ; modifiers from the event record
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT IsAppWindow
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- CLR.W -(SP) ; space for result of IsAppWindow
- MOVE.L WindowPtr(A6),-(SP) ; pass the window pointer
- BSR IsAppWindow ; test if this window was ours
- MOVE.W (SP)+,D0 ; get the result
- CMPI.W #True,D0 ; it must be our window
- BNE.S Exit ; it wasn't our window
-
- CMPI.W #True,Active(A6) ; was it an Activate?
- BNE.S DeActivate ; no, perform a Deactivate
-
- * do the activate event processing here, then "BRA.S Exit"
-
- DeActivate ; do the deactivate event
-
- * do the deactivate event processing here, then fall through to Exit
-
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo Activate ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE DoMenuCommand(menuResult: LONGINT);
- * ================================================
- * This is called when an item is chosen from the menu bar (after calling
- * MenuSelect or MenuKey). It performs the right operation for each command.
- * It is good to have both the result of MenuSelect and MenuKey go to
- * one routine like this to keep everything organized.
-
- SEG 'Main' ; case sensitive
- DoMenuCommand PROC
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- MenuItem DS.W 1 ; result from _MenuKey or _MenuSelect
- MenuID DS.W 1 ; caller passed a long word, ID + Item
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- Deskname DS.B 256 ; local storage for Desk Accs name
- TempPort DS.L 1 ; local storage for the current port
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT SetLight,DoCloseWindow,Terminate
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W MenuID(A6),D0 ; a nifty Pascal case-like macro
- CASE#.W (D0,IF), \
- (AppleMenu, DoAppleMenu), \
- (FileMenu, DoFileMenu)
- ; add additional Menus would go here
- BRA.W Exit ; otherwise we will exit this procedure
-
- * ------------- THE APPLE MENU ROUTINES -------------
- DoAppleMenu
- CMPI.W #AboutItem,MenuItem(A6) ; was it the about item?
- BNE.S @1 ; no, must be a Desk Acc
-
- CLR.W -(SP) ; show the About dialog
- MOVE.W #rAboutAlert,-(SP) ; resource for alert dialog
- CLR.L -(SP) ; no filter procedure used here
- _Alert ; read the resource and display it
- MOVE.W (SP)+,D0 ; I don't care which item is was
- BRA.W Exit ; all done with with Apple menu
-
- @1 PEA TempPort(A6) ; open a desk accessory
- _GetPort ; save the current port
- CLR.L -(SP) ; space for result of GetMHandle
- MOVE.W #AppleMenu,-(SP)
- _GetMHandle ; put Apple menu on stack
- MOVE.W MenuItem(A6),-(SP) ; and here's the MenuItem
- PEA DeskName(A6) ; now tell me the DA's name
- _GetItem
- CLR.W -(SP) ; space for OpenDeskAcc result
- PEA DeskName(A6)
- _OpenDeskAcc ; open that puppy
- MOVE.W (SP)+,D0 ; result
- MOVE.L TempPort(A6),-(SP) ; restore the port
- _SetPort
- BRA.S Exit
-
- * ------------- THE FILE MENU ROUTINES -------------
- DoFileMenu
- MOVE.W MenuItem(A6),D0 ; test the MenuItem
- Case#.W (D0,IF), \
- (NewItem, FileNew), \
- (CloseItem, FileClose), \
- (QuitItem, FileQuit)
- BRA.S Exit ; add additional menus here
- FileNew:
- BSR OpenClutWind
- BRA.S Exit
- FileClose
- CLR.L -(SP) ; bug fix, didn't clear space for result -JDR 2/27/89
- _FrontWindow
- BSR DoCloseWindow ; close the window
- BRA.S Exit
-
- FileQuit BSR Terminate ; let's get out of here
-
- Exit CLR.W -(SP)
- _HiLiteMenu ; unhilite all Menus
- UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo DoMenuCm ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE OpenWindow(WINDid:Integer,WDataSize:Long,UpdateRtn:ProcPtr,MouseRtn:ProcPtr):WindowPtr
- * ================================================
- SEG 'Main' ; case sensitive
- OpenWindow PROC EXPORT
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result1 DS.L 1
- ParamBegin EQU * ; start parameters after this point
- rWindow DS.W 1 ; Id of WIND resource to use
- WDataSize DS.L 1 ; Size of window data record to allocate
- ProcPtr DS.L 1 ; Pointer to update routine for this window
- MouseRtn DS.L 1
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- * insert locals here
- TempWord DS.W 1
- TempLong DS.L 1
- LocalSize EQU * ; size of all the local variables
- ENDR
- IMPORT AlertUser
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.L #windowSize,D0
- _NewPtr ,Clear ; create a pointer in A0 and clear memory
- CMPA.L #NIL,A0 ; check for NIL pointer (result in D0)
- BNE.S @1 ; must have been a valid pointer
- Move.w #25,-(SP) ; Error #
- Pea #'OpenWindow1' ; Routine Name
- Pea #'No Memory for Window Record' ; Message
- JMP AlertUser ; couldn't get memory, report error
- @1 CLR.L -(SP) ; create space for result
- MOVE.W rWindow(A6),-(SP) ; out window resource definition
- MOVE.L A0,-(SP) ; our window record storage
- MOVE.L #-1,-(SP) ; make it on top
- _GetNewCWindow ; create the window
- Move.l (SP)+,Result1(A6)
-
- MOVE.L WDataSize(A6),D0
- _NewHandle ,Clear ; create a pointer in A0 and clear memory
- CMPA.L #NIL,A0 ; check for NIL pointer (result in D0)
- BNE.S @2 ; must have been a valid pointer
- Move.w #25,-(SP) ; Error #
- Pea #'OpenWindow2' ; Routine Name
- Pea #'No Memory for Window Record' ; Message
- JMP AlertUser ; couldn't get memory, report error
- @2 Move.l A0,-(SP) ; Save address
- Move.l Result1(A6),-(SP)
- Move.l A0,-(SP)
- _SetWRefCon
- Move.l (SP)+,A0 ; restore address
- Move.l (A0),A0
- WITH ClutWData
- Move.l ProcPtr(A6),UpdateRtn(A0) ; Update routine
- Move.l MouseRtn(A6),MouseDnRtn(A0) ; Mouse down routine
- ENDWITH
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo OpenWindow
- ENDP
-
- * ================================================
- * PROCEDURE DoMouseDown(Event: EventRecord);
- * ================================================
- * Handle all of the MouseDown events.
-
- SEG 'Main' ; case sensitive
- DoMouseDown PROC
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- EventPtr DS.L 1 ; pointer to current event
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- WindowPtr DS.L 1 ; local Window pointer variable
- Where DS.L 1 ; local variable where the click was
- NewGrowRect DS Rect ; local rect variable for SizeWindow
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT AdjustMenus,DoContentClick
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVEA.L EventPtr(A6),A0 ; event record only needed by SystemClick
- MOVE.L evtMouse(A0),Where(A6) ; make a local copy of the mouse location
-
- CLR.W -(SP) ; space for FindWindow result
- MOVE.L Where(A6),-(SP) ; the mouse point
- PEA WindowPtr(A6) ; a local variable
- _FindWindow ; put the result in a register
- MOVE.W (SP)+,D0 ; a nifty Pascal case-like macro
- Case#.W (D0,IF), \
- (InMenuBar, MenuEvent), \
- (InSysWindow, SystemEvent), \
- (InContent, Content), \
- (InDrag, Drag)
- ; add additional routines here
- BRA.S Exit ; otherwise we will exit this procedure
-
- * ------------- THE DESK ACCS EVENT -------------
- MenuEvent
- BSR.W AdjustMenus
- CLR.L -(SP) ; space for MenuSelect
- MOVE.L Where(A6),-(SP) ; Mouse coordinates
- _MenuSelect ; pass MenuSelect's result
- BSR DoMenuCommand ; go do the menu and return
- BRA.S Exit
-
- * ------------- THE DESK ACCS EVENT -------------
- SystemEvent
- MOVE.L EventPtr(A6),-(SP) ; get EventRecord and WindowPtr
- MOVE.L WindowPtr(A6),-(SP) ; pass the window pointer and...
- _SystemClick ; let the system handle it
- BRA.S Exit
-
- * ------------- THE CONTENT EVENT -------------
- Content
- CLR.L -(SP) ; was our window in front?
- _FrontWindow ; get front window's pointer
- MOVE.L (SP)+,D0
- CMP.L WindowPtr(A6),D0 ; was it in the front window?
- BNE.S @1 ; no, then just select window
-
- Clr.l -(SP)
- MOVE.L WindowPtr(A6),-(SP)
- _GetWRefCon
- Move.l (SP)+,A2 ; Retrieve handle
- Move.l (A2),A0 ; Deref Handle
- WITH ClutWData
- Move.l MouseDnRtn(A0),A0 ; Get ProcPtr
- ENDWITH
- MOVE.L WindowPtr(A6),-(SP) ; pass the window pointer
- MOVE.L EventPtr(A6),-(SP) ; pass a pointer to the event
- JSR (A0)
- BRA.S Exit
-
- @1 MOVE.L WindowPtr(A6),-(SP) ; only select this window
- _SelectWindow ; and take no further action
- BRA.S Exit
-
- * ------------- THE DRAG A WINDOW EVENT -------------
- Drag
- MOVE.L WindowPtr(A6),-(SP) ; pass Window Pointer
- MOVE.L Where(A6),-(SP) ; Mouse coordinates and boundary
- PEA QD.Screenbits.bounds
- _DragWindow ; drag it the screen's boundary
-
- Exit
- UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo MouseDwn ; this name will appear in the debugger
- ENDP
-
-
- * ================================================
- * PROCEDURE DoEvent(event: EventRecord);
- * ================================================
- * Do the right thing for an event. Determine what kind of event it is,
- * and call the appropriate routines.
-
- SEG 'Main' ; case sensitive
- DoEvent PROC
-
- ModifyReg EQU D4 ; we'll use this register locally
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start listing parameters here
- EventPtr DS.L 1 ; pointer to current event
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- TheEvent DS EventRecord ; local copy of the event record
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT DoMouseDown,DrawWindow, \
- AdjustMenus,IsAppWindow,\
- DoUpdate,DoActivate
-
- WITH StackFrame,TheEvent ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
- MOVEM.L ModifyReg,-(SP) ; save this register before using it
-
- MOVEA.L EventPtr(A6),A0 ; pointer of event passed by caller
- LEA TheEvent(A6),A1 ; pointer to local variable TheEvent
- MOVE.L #evtBlkSize,D0 ; size of an event record
- _BlockMove ; we now have a local copy of the event
-
- MOVE.W Modify(A6),ModifyReg ; a nifty Pascal case-like macro
- MOVE.W What(A6),D0 ; get the event number
- Case# (D0,Exit), \ ; if not an event we support, then exit
- , \ ; 0 Null (not used)
- MouseDown, \ ; 1 Mouse down
- , \ ; 2 Mouse up (not used)
- KeyDown, \ ; 3 Key down
- , \ ; 4 Key up (not used)
- KeyDown, \ ; 5 Auto key
- Update, \ ; 6 Update
- Disk, \ ; 7 Disk inserted
- Activate, \ ; 8 Activate/Deactivate
- , \ ; 9 (not used)
- , \ ; 10 Network (not used)
- , \ ; 11 I/O Driver (not used)
- , \ ; 12 App1 (not used)
- , \ ; 13 App2 (not used)
- , \ ; 14 App3 (not used)
- OSEvent, ; 15 OS Event or Suspend/Resume
-
-
- * ------------- THE MOUSEDOWN EVENT -------------
- MouseDown
- PEA TheEvent(A6) ; pass Event pointer in case of SystemClick
- BSR DoMouseDown
- BRA Exit
-
- * ------------- THE KEYDOWN EVENT -------------
- KeyDown
- BTST #CmdKey,ModifyReg ; command key?
- BEQ Exit ; no, then we're done
- BSR.W AdjustMenus ; first, adjust the menus
- CLR.L -(SP) ; space for MenuKey
- MOVE.W 2+Message(A6),-(SP) ; get the character
- _MenuKey ; is it a command?
- BSR DoMenuCommand ; handle the command and return
- BRA.S Exit
-
- * ------------- THE UPDATE EVENT -------------
- Update
- MOVE.L Message(A6),-(SP) ; pass the window pointer
- BSR DoUpdate ; do the update
- BRA.S Exit
-
- * ------------- THE DISK EVENT -------------
- Disk
- TST.W Message(A6) ; check for error
- BEQ.S @1 ; if none, skip
- CLR.W -(SP)
- MOVE.L #DITopLeft,-(SP)
- MOVE.L Message(A6),-(SP)
- MOVE.W #diBadMount,-(SP)
- _Pack2 ; go through disk init package
- ADDQ #2,SP ; throw away result
- @1 BRA.S Exit
-
- * ------------- THE ACTIVATE/DEACTIVATE EVENT -------------
- Activate
- BTST #ActiveFlag,ModifyReg ; was it an Activate?
- BEQ.S @1 ; no, perform a Deactivate
-
- MOVE.L Message(A6),-(SP) ; pass the current window pointer
- MOVE.W #True,-(SP) ; set up for an Activate event
- BSR DoActivate ; do the activate routine
- BRA.S Exit ; we're done
-
- @1 MOVE.L Message(A6),-(SP) ; pass current window pointer
- MOVE.W #False,-(SP) ; set up for an Deactivate event
- BSR DoActivate ; go do the activate routine
- BRA.S Exit ; we're done
-
- * ------------- THE SUSPEND/RESUME EVENT -------------
- * OSEvent is the event number of the suspend/resume and mouse-moved events sent
- * by MultiFinder. Once we determine that an event is an osEvent, we look at the
- * high byte of the message sent to determine which kind it is. To differentiate
- * suspend and resume events we check the resumeMask bit.
-
- OSEvent MOVE.B Message(A6),D1 ; get high byte of Message in reg
- CMPI.B #SuspendResume,D1 ; test for message event type
- BNE.S Exit ; not a suspend/resume event
-
- BTST #0,3+Message(A6) ; test bit zero in low byte of Message
- BNE.S @1 ; this is a resume event
-
- MOVE.W #True,G.InBackground ; a suspend event
- CLR.L -(SP) ; bug fix, was passing Message to DoActivate -JDR 2/27/89
- _FrontWindow ; pass the front window to DoActivate -JDR 2/27/89
- MOVE.W #False,-(SP) ; pass false to cause deactivate
- BSR DoActivate ; go do the activate routine
- BRA.S Exit
-
- @1 MOVE.W #False,G.InBackground ; a resume event
- CLR.L -(SP) ; bug fix, was passing Message to DoActivate -JDR 2/27/89
- _FrontWindow ; pass the front window to DoActivate -JDR 2/27/89
- MOVE.W #True,-(SP) ; pass false to cause activate
- BSR DoActivate ; go do the activate routine
-
- Exit
- MOVEM.L (SP)+,ModifyReg ; restore this register after use
- UNLK A6
- MOVEA.L (SP)+,A0 ; save the caller's address
- ADDA.L #ParamSize,SP ; strip the caller's parameters
- JMP (A0)
-
- DbgInfo DoEvent ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE EventLoop;
- * ================================================
- * Get the events by calling WaitNextEvent, if it's available, otherwise
- * by calling GetNextEvent. Also call AdjustCursor before doing the event.
- * After returning from handling the event, we have to make sure the cursor
- * is still adjusted proper ONLY because this application can "sleep" forever.
-
- * An event record is allocated on the stack. A pointer to this event is
- * passed to "DoEvent". We loop until the user has selects "Quit" in the
- * file menu. This program will exit through the DoMenuCommand routine.
-
- * 1.02 made adjustments to the event loop logic. There was a bug in calling
- * AdjustCursor at the wrong time. (it crashed under _GetNextEvent too!)
-
- * If you are using modeless dialogs that have editText items,
- * you will want to call IsDialogEvent to give the caret a chance
- * to blink, even if WNE/GNE returned FALSE. However, check FrontWindow
- * for a non-NIL value before calling IsDialogEvent.
-
- SEG 'Main' ; case sensitive
- EventLoop PROC ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start listing parameters here
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- TheEvent DS EventRecord ; local copy of the event record
- MouseMvdRgn DS.L 1 ; local region for MouseMoved events
- MousePos DS.L 1 ; local point for mouse position
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT AdjustCursor,GetGlobalMouse
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- CLR.L -(SP)
- _NewRgn ; create region for AdjustCursor
- MOVE.L (SP)+,MouseMvdRgn(A6) ; save the handle to this region
-
- * ------------- GET NEXT EVENT LOOP -------------
- NextEvent
- CMPI.W #True,G.HasWNEvent ; see if we can call WaitNextEvent
- BNE.S @1 ; nope, old time events
-
- PEA MousePos(A6) ; here's the mouse
- BSR GetGlobalMouse ; get global coordinate
- MOVE.L MousePos(A6),-(SP) ; here's the mouse
- MOVE.L MouseMvdRgn(A6),-(SP) ; the region to change
- BSR AdjustCursor ; adjust the cursor and region
- CLR.W -(SP) ; space for result
- MOVE.W #EveryEvent,-(SP) ; the events we want
- PEA TheEvent(A6) ; pointer to the event record
- MOVE.L #SleepValue,-(SP) ; the sleeping time value
- MOVE.L MouseMvdRgn(A6),-(SP) ; the current MouseRgn
- _WaitNextEvent
- BRA.S @2 ; got an event to handle?
-
- ; no WaitNextEvent trap available
- @1 _SystemTask ; call SystemTask for drivers and DAs
- CLR.W -(SP) ; space for result
- MOVE.W #EveryEvent,-(SP) ; the events we want
- PEA TheEvent(A6) ; pass a pointer to our event
- _GetNextEvent
- @2 MOVE.W (SP)+,D0 ; result code
- BEQ.S NextEvent ; no event, get another one
-
- GotEvent MOVE.L TheEvent.where(A6),-(SP); the mouse location
- MOVE.L MouseMvdRgn(A6),-(SP) ; the region to change
- BSR AdjustCursor ; adjust cursor BEFORE doing event
- PEA TheEvent(A6) ; pass the pointer to our event
- BSR DoEvent ; do the event and return
-
- BRA.S NextEvent ; done with that event, get the next
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo EvntLoop ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * --------------- MAIN ENTRY POINT ---------------
- * ================================================
- * This is the entry point of the program. We start with data initializing
- * and then to get the System environment (SysEnvirons). We unload the
- * initialization code segment and finally get started with the EventLoop.
-
- SEG 'Main' ; case sensitive
- StartUp MAIN ; entry point of the program
-
- IMPORT _DataInit,Initialize, \
- ForceEnvirons,EventLoop
-
- JSR _DataInit ; initialize those constants
- PEA _DataInit ; get rid of that segment
- _UnloadSeg
-
- * If you have stack requirements that differ from the default, then you could
- * use SetApplLimit to increase StackSpace at this point, before calling MaxApplZone.
-
- _MaxApplZone ; result in D0
- JSR Initialize ; get things the program set up
- PEA Initialize
- _UnloadSeg ; we're done this that segment too
-
- * ------------- SET UP THE CLUT WINDOW -------------
- BSR OpenClutWind
-
-
- LEA EventLoop,A0 ; on your mark, get set,...
- JMP (A0) ; go into the event loop
- ENDP
-
- END ; end of this source file
-
-